
// Yast backbone lib

// Debug print
var __ = function(str){ 
	if(typeof(console.log) != 'undefined'){
		console.log(str); 
	}	
};

// Define Yast scope
window.Yast = {
    models:{
        classes:{
            Record:null,
            Record:null
        }
    },

    helpers:{
        addZero:function (num) {
            (String(num).length < 2) ? num = String("0" + num) : num = String(num);
            return num;
        },
        date:new Date(),
		startOfWeek: function(d){
		  var day = d.getDay(),
		  diff = d.getDate() - day + (day == 0 ? -6:1); // adjust when day is sunday
		  return new Date(d.setDate(diff));
		},
		formattedTimeSpan: function(from, to){
			var total = (to-from)/1000;
			var hours = Math.floor(total / 3600);
			var minutes = Math.floor((total - (3600 * hours)) / 60);

			var textTotal = window.Yast.helpers.addZero(hours) + ':' + window.Yast.helpers.addZero(minutes);
			return textTotal;
		},

		getDaysInMonth: function(i){
			return 32 - new Date(i.getFullYear(), i.getMonth(), 32).getDate();
		},

		getStartOfDay: function(i){
			var d = new Date(i.getFullYear(), i.getMonth(), i.getDate());
			return d;
		},
		getEndOfDay: function(i){
			var d = new Date(i.getFullYear(), i.getMonth(), i.getDate(), 23, 59, 59, 000);
			return d;
		},
		getStartOfWeek: function(i){
			var d = new Date(i.getFullYear(), i.getMonth(), i.getDate() - i.getDay());
			return d;
		},
		getStartOfWeek: function(i){
			var d = new Date(i.getFullYear(), i.getMonth(), i.getDate() - i.getDay());
			return d;
		},
		getEndOfWeek: function(i){
			var d = new Date(i.getFullYear(), i.getMonth(), i.getDate() + (6 - i.getDay()), 23, 59, 59, 000);
			return d;
		},
		getStartOfMonth: function(i){
			var d = new Date(i.getFullYear(), i.getMonth());
			return d;
		},
		getEndOfMonth: function(i){
			var d = new Date(i.getFullYear(), i.getMonth(), window.Yast.helpers.getDaysInMonth(i), 23, 59, 59, 000);
			return d;
		}

    }
};

// Fill the Yast namespace
window.Yast._init = function(){

	// Base model, takes care of proper typing of attributes
	window.Yast.models.classes.YastModel = Backbone.Model.extend({
		set: function(attrs, options){
			// Enforce correct data type
			for (attr in attrs) {
				var type = typeof(this.defaults[attr]);
				if(type == 'undefined' && attr == 'id') type = 'number';
				switch(type){
					case 'number':
						attrs[attr] = parseFloat(attrs[attr]);
						break;
					case 'text':
						attrs[attr] = attrs[attr]+'';
						break;
				}
			}
			Backbone.Model.prototype.set.call(this, attrs, options);
			return this;		
		}
	});

	window.Yast.models.classes.Record = window.Yast.models.classes.YastModel.extend({
		defaults:{
			typeId:1,
			project:0,
			variables:[0, 0, "", 0],
			flags:0
		},
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"data.getRecords"
		},
		parse: function(response){
			if(typeof response.data != 'undefined')
				return response.data.objects[0].record;
			return response.record;
		},

		initialize:function (attributes, options) {
			this.attributes = attributes;
			this.id = this.attributes.id;
		},

		getProject:function () {
			return window.Yast.models.projects.get(this.get("project"));
		},

		getFromDate:function () {
			return new Date(this.get('variables')[0] * 1000);
		},

		getToDate:function () {
			return new Date(this.get('variables')[1] * 1000);
		},

		getComment:function () {
			return this.get('variables')[2];
		},

		isRunning:function () {
			return (this.get('variables')[3] == 1);
		},

		stopTimer:function () {
			var now = Math.floor(new Date().getTime() / 1000);
			var existing_variables = this.get("variables");
			this.set({variables:[existing_variables[0], now, existing_variables[2], 0]});
			this.save();
		},

		startTimer:function () {
			var now = Math.floor(new Date().getTime() / 1000);
			this.set({variables:[now, 0, "", 1]});
			this.save();
			window.Yast.models.records.add(this);
		},

		isToday:function () {
			var fromDate = this.getFromDate();
			var todayDate = new Date();
			return fromDate.getYear() == todayDate.getYear() && fromDate.getMonth() == todayDate.getMonth() && fromDate.getDate() == todayDate.getDate();
		},

		getDuration:function () {
			var nowTime = Math.floor(new Date().getTime() / 1000);
			var fromTime = Math.floor(this.getFromDate().getTime() / 1000);
			var toTime = Math.floor(this.getToDate().getTime() / 1000);

			if (this.isRunning()) {
				return nowTime - fromTime;
			} else {
				return toTime - fromTime;
			}
		},

		getDurationString:function (showSeconds) {
			var d = this.getDuration();
			if(d < 60 && (typeof(showSeconds) != 'undefined' && showSeconds)){
				return d+' sec';
			}else{
				var hours = Math.floor(d / 3600);
				var minutes = Math.floor((d - (3600 * hours)) / 60);

				return hours + ':' + window.Yast.helpers.addZero(minutes);
			}
		}
	});

	window.Yast.models.classes.RecordStore = Backbone.Collection.extend({
		model:window.Yast.models.classes.Record,
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"data.getRecords"
		},
		comparator:function (record) {
			var v = record.get("variables");
			return v?-record.get("variables")[0]:0;
		},
		parse: function(response){
			return response.data.objects;
		}
	});

	window.Yast.models.classes.RecordType = Backbone.Model.extend({
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"meta.getRecordTypes"
		},
		initialize:function () {
			this.id = this.attributes.id;
		}
	});

	window.Yast.models.classes.RecordTypeStore = Backbone.Collection.extend({
		model:window.Yast.models.classes.RecordType,
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"meta.getRecordTypes"
		}
	});

	window.Yast.models.classes.ProjectTreeNode = Backbone.Model.extend({
	});

	window.Yast.models.classes.Project = window.Yast.models.classes.ProjectTreeNode.extend({
		defaults:{
			name:"",
			description:"",
			primaryColor:"",
			parentId:0
		},
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"data.getProjects"
		},
		parse: function(response){
			if(typeof response.data != 'undefined')
				return response.data.objects[0].project;
			return response.project;
		},
		initialize:function (attributes, options) {
			this.attributes = attributes;
			this.id = this.attributes.id;
		},

		getLatestRecord:function () {
			var project = this;
			return _.find(window.Yast.models.records.models, function (record) {
				return (record.get("project") == project.id);
			});
		},

		getRunningRecord:function () {
			var project = this;
			return _.find(window.Yast.models.records.models, function (record) {
				return (record.get("project") == project.id && record.get("variables")[3] == 1);
			});
		},

		hasRunning:function () {
			var t = this.getRunningRecord();
			return !(typeof t == "undefined");
		},

		getId:function () {
			return this.get('id');
		}
	});

	window.Yast.models.classes.ProjectStore = Backbone.Collection.extend({
		model:window.Yast.models.classes.Project,
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"data.getProjects"
 		},
		parse: function(response){
			return response.data.objects;
		}
	});

	window.Yast.models.classes.VariableType = Backbone.Model.extend({
		initialize:function () {
			this.id = this.attributes.id;
		}
	});

	window.Yast.models.classes.VariableTypeStore = Backbone.Collection.extend({
		model:window.Yast.models.classes.VariableType
	});

	window.Yast.models.classes.Folder = window.Yast.models.classes.ProjectTreeNode.extend({
		defaults:{
			name:"",
			description:"",
			primaryColor:"",
			parentId:0
		},
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"data.getFolders"
		},
		parse: function(response){
			if(typeof response.data != 'undefined')
				return response.data.objects[0].folder;
			return response.folder;
		},
		initialize:function (attributes, options) {
			this.attributes = attributes;
			this.id = this.attributes.id;
		},
		getProjects: function(){
			
			var projects = new Backbone.Collection();
			parentId = this.id;
			projects.add(_.filter(window.Yast.models.projects.models, function(e){
				return e.attributes.parentId == parentId;
			}));
			return projects;

		}
	});

	window.Yast.models.classes.FolderStore = Backbone.Collection.extend({
		model:window.Yast.models.classes.Folder,
		requestMap:{
			'create':"data.add",
			'update':"data.change",
			'delete':"data.delete",
			'read':"data.getFolders"
		},
		parse: function(response){
			return response.data.objects;
		}
	});


	// Helper function that will build a tree of the projects and folders
	window.Yast.getProjectTree = function(){
		
		var map = {};
		_.each([this.models.projects.models, this.models.folders.models], function(f){
			_.each(f, function(e){
				if(typeof map[e.attributes.parentId] == 'undefined'){
					map[e.attributes.parentId] = [];
				}
				map[e.attributes.parentId].push({id: e.id, parentId: e.attributes.parentId, object: e, children: null});
			});
		});

		var tree = {id: 0, parentId: 0, object: null, children: null};
		var _walk = function(t){
			if(typeof map[t.id] != 'undefined'){
				t.children = map[t.id];
				delete map[t.id];
			}else{
				t.children = [];
			}
			for(var i=0; i<t.children.length;i++){
				_walk(t.children[i]);
			}
		};
		_walk(tree);
		__('Done building');

		return tree;

	}

	window.Yast.models.projects = new window.Yast.models.classes.ProjectStore();
	window.Yast.models.records = new window.Yast.models.classes.RecordStore();
	window.Yast.models.folders = new window.Yast.models.classes.FolderStore();

	window.Yast.login = function (username, password, successCallback, failureCallback) {

		localStorage.setItem("yast_user", username);

		var request = {
			"req":"auth.login",
			"data":{
				"user": username,
				"password": password
			}
		};
		jQuery.getJSON('http://wwwy.ast.com/1.0/?lang=javascript&jsonp=?&request=' + encodeURIComponent(Backbone.JSON.stringify(request)),
			function (response) {
				// verify login
				if(response.status === 0 && response.data.hash.length > 0) {
					localStorage.setItem("yast_hash", response.data.hash);
					__("Logged in succesfully");
					if(successCallback) successCallback(response);
				} else {
					localStorage.setItem("yast_hash", "");
					if(failureCallback) failureCallback(response);
				}
			}
		);

	};

	window.Yast.logout = function(){
		
		for (var i = 0; i < localStorage.length; i++){
			if(/yast/.test(localStorage.key(i))){
				__('sletter '+localStorage.key(i));
				localStorage.removeItem(localStorage.key(i));
			}
		}

		window.Yast.models.projects.reset();
		window.Yast.models.records.reset();
		window.Yast.models.folders.reset();

		document.cookie = "YASTAPI=; expires=Thu, 01-Jan-70 00:00:01 GMT;";

	};



}
 
// Bootstrap!



// Init app
window.Yast._init();


